#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <time.h>

#include "cJSON.h"
#include "common.h"

// 线程池函数声明
typedef struct ThreadPool ThreadPool;
ThreadPool *threadPoolCreate(int threadCount, int queueCapacity);
int threadPoolAddTask(ThreadPool *pool, void (*function)(void *), void *argument);
void threadPoolDestroy(ThreadPool *pool);

// 日志函数声明
enum LogLevel { LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, LOG_LEVEL_ERROR, LOG_LEVEL_FATAL };
int logInit(const char *filename, enum LogLevel level, int consoleOutput);
void logCleanup();
void logDebug(const char *format, ...);
void logInfo(const char *format, ...);
void logWarning(const char *format, ...);
void logError(const char *format, ...);
void logFatal(const char *format, ...);

// 心跳函数声明
typedef struct ConnectionStatus ConnectionStatus;
typedef struct HeartbeatConfig HeartbeatConfig;
ConnectionStatus *connectionStatusInit();
void connectionStatusUpdate(ConnectionStatus *status);
int connectionStatusCheckTimeout(ConnectionStatus *status, int timeout);
void connectionStatusDestroy(ConnectionStatus *status);
HeartbeatConfig *heartbeatInit(int interval, int timeout, int (*sendFunc)(void *), void *context);
int heartbeatStart(HeartbeatConfig *config);
void heartbeatStop(HeartbeatConfig *config);
void heartbeatDestroy(HeartbeatConfig *config);

#define SERVER_PORT 8080
#define MAX_EVENTS 1024
#define MAX_CLIENT_COUNT 100
#define THREAD_POOL_SIZE 8
#define TASK_QUEUE_SIZE 1000

// 客户端连接信息
typedef struct {
    int sockfd;
    struct sockaddr_in addr;
    ConnectionStatus *connStatus;
} ClientInfo;

// 任务数据
typedef struct {
    ClientInfo *client;
    char *data;
    int dataLen;
    unsigned char dataType;
} TaskData;

// 全局变量
ThreadPool *g_threadPool = NULL;
int g_epollfd = -1;
ClientInfo *g_clients[MAX_CLIENT_COUNT];
int g_clientCount = 0;

// 处理硅片数据
void processSiliconWaferData(ClientInfo *client, cJSON *root) {
    cJSON *batchData = cJSON_GetObjectItem(root, "batchSiliconWaferData");
    if (batchData && cJSON_IsArray(batchData)) {
        int arraySize = cJSON_GetArraySize(batchData);
        logInfo("Received %d silicon wafer data records from client %s:%d", 
                arraySize, inet_ntoa(client->addr.sin_addr), ntohs(client->addr.sin_port));
        
        // 处理每条硅片数据
        for (int i = 0; i < arraySize; i++) {
            cJSON *item = cJSON_GetArrayItem(batchData, i);
            if (item) {
                char *waferId = cJSON_GetObjectItem(item, "waferId")->valuestring;
                char *defectType = cJSON_GetObjectItem(item, "defectType")->valuestring;
                double efficiency = cJSON_GetObjectItem(item, "efficiency")->valuedouble;
                
                logDebug("Wafer ID: %s, Defect Type: %s, Efficiency: %.2f", 
                        waferId, defectType, efficiency);
                
                // 这里可以添加数据存储逻辑
            }
        }
    }
}

// 处理生产数据
void processProductionData(ClientInfo *client, cJSON *root) {
    cJSON *prodData = cJSON_GetObjectItem(root, "productionData");
    if (prodData && cJSON_IsObject(prodData)) {
        char *shift = cJSON_GetObjectItem(prodData, "shift")->valuestring;
        char *time = cJSON_GetObjectItem(prodData, "time")->valuestring;
        char *lineNo = cJSON_GetObjectItem(prodData, "lineNo")->valuestring;
        int output = cJSON_GetObjectItem(prodData, "output")->valueint;
        double qualifiedRate = cJSON_GetObjectItem(prodData, "qualifiedRate")->valuedouble;
        
        logInfo("Received production data from client %s:%d - Line: %s, Shift: %s, Output: %d, Qualified Rate: %.2f%%", 
                inet_ntoa(client->addr.sin_addr), ntohs(client->addr.sin_port),
                lineNo, shift, output, qualifiedRate * 100);
        
        // 这里可以添加数据存储逻辑
    }
}

// 线程池任务处理函数
void handleClientData(void *arg) {
    TaskData *task = (TaskData *)arg;
    ClientInfo *client = task->client;
    char *data = task->data;
    unsigned char dataType = task->dataType;
    
    logDebug("Processing data type %d from client %s:%d", 
            dataType, inet_ntoa(client->addr.sin_addr), ntohs(client->addr.sin_port));
    
    // 解析JSON数据
    cJSON *root = cJSON_Parse(data);
    if (root) {
        // 根据数据类型处理
        switch (dataType) {
            case DATA_TYPE_SILICON_WAFER:
                processSiliconWaferData(client, root);
                break;
            case DATA_TYPE_PRODUCTION:
                processProductionData(client, root);
                break;
            case DATA_TYPE_HEARTBEAT:
                // 更新连接状态
                connectionStatusUpdate(client->connStatus);
                logDebug("Received heartbeat from client %s:%d", 
                        inet_ntoa(client->addr.sin_addr), ntohs(client->addr.sin_port));
                break;
            default:
                logWarning("Unknown data type: %d from client %s:%d", 
                        dataType, inet_ntoa(client->addr.sin_addr), ntohs(client->addr.sin_port));
                break;
        }
        
        // 发送确认包
        cJSON *response = cJSON_CreateObject();
        cJSON_AddStringToObject(response, "status", "success");
        cJSON_AddNumberToObject(response, "timestamp", time(NULL));
        
        char *responseStr = cJSON_PrintUnformatted(response);
        sendPacket(client->sockfd, DATA_TYPE_ACK, responseStr);
        
        cJSON_free(responseStr);
        cJSON_Delete(response);
        cJSON_Delete(root);
    } else {
        logError("Failed to parse JSON data from client %s:%d", 
                inet_ntoa(client->addr.sin_addr), ntohs(client->addr.sin_port));
        
        // 发送错误包
        cJSON *response = cJSON_CreateObject();
        cJSON_AddStringToObject(response, "status", "error");
        cJSON_AddStringToObject(response, "message", "Invalid JSON format");
        
        char *responseStr = cJSON_PrintUnformatted(response);
        sendPacket(client->sockfd, DATA_TYPE_ERROR, responseStr);
        
        cJSON_free(responseStr);
        cJSON_Delete(response);
    }
    
    free(data);
    free(task);
}

// 设置非阻塞模式
int setNonBlocking(int fd) {
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags < 0) {
        return -1;
    }
    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}

// 添加客户端到epoll
void addClientToEpoll(int epollfd, int sockfd, struct sockaddr_in addr) {
    struct epoll_event event;
    
    // 创建客户端信息
    ClientInfo *client = (ClientInfo *)malloc(sizeof(ClientInfo));
    client->sockfd = sockfd;
    client->addr = addr;
    client->connStatus = connectionStatusInit();
    
    // 设置非阻塞
    setNonBlocking(sockfd);
    
    // 添加到epoll
    event.events = EPOLLIN | EPOLLET;
    event.data.ptr = client;
    epoll_ctl(epollfd, EPOLL_CTL_ADD, sockfd, &event);
    
    // 添加到客户端列表
    g_clients[g_clientCount++] = client;
    
    logInfo("New client connected: %s:%d", 
            inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
}

// 从epoll中移除客户端
void removeClientFromEpoll(int epollfd, ClientInfo *client) {
    // 从epoll中移除
    epoll_ctl(epollfd, EPOLL_CTL_DEL, client->sockfd, NULL);
    close(client->sockfd);
    
    // 从客户端列表中移除
    for (int i = 0; i < g_clientCount; i++) {
        if (g_clients[i] == client) {
            g_clients[i] = g_clients[g_clientCount - 1];
            break;
        }
    }
    g_clientCount--;
    
    // 释放资源
    connectionStatusDestroy(client->connStatus);
    free(client);
    
    logInfo("Client disconnected");
}

// 检查客户端连接状态
void checkClientStatus() {
    while (1) {
        sleep(5);  // 每5秒检查一次
        
        for (int i = 0; i < g_clientCount; i++) {
            ClientInfo *client = g_clients[i];
            if (connectionStatusCheckTimeout(client->connStatus, 30)) {  // 30秒超时
                logWarning("Client %s:%d timeout, disconnecting", 
                        inet_ntoa(client->addr.sin_addr), ntohs(client->addr.sin_port));
                removeClientFromEpoll(g_epollfd, client);
                i--;  // 调整索引
            }
        }
    }
}

// 主函数
int main() {
    int serverfd, clientfd;
    struct sockaddr_in serverAddr, clientAddr;
    socklen_t clientAddrLen;
    struct epoll_event events[MAX_EVENTS];
    pthread_t checkThread;
    
    // 初始化日志
    logInit("server.log", LOG_LEVEL_INFO, 1);
    logInfo("Starting server...");
    
    // 创建线程池
    g_threadPool = threadPoolCreate(THREAD_POOL_SIZE, TASK_QUEUE_SIZE);
    if (!g_threadPool) {
        logFatal("Failed to create thread pool");
    }
    
    // 创建服务器套接字
    serverfd = createTCPServer(SERVER_PORT, 10);
    if (serverfd < 0) {
        logFatal("Failed to create server socket");
    }
    
    // 设置非阻塞
    setNonBlocking(serverfd);
    
    // 创建epoll
    g_epollfd = epoll_create1(0);
    if (g_epollfd < 0) {
        logFatal("Failed to create epoll");
    }
    
    // 添加服务器套接字到epoll
    struct epoll_event event;
    event.events = EPOLLIN | EPOLLET;
    event.data.fd = serverfd;
    epoll_ctl(g_epollfd, EPOLL_CTL_ADD, serverfd, &event);
    
    // 启动连接状态检查线程
    pthread_create(&checkThread, NULL, (void *)checkClientStatus, NULL);
    
    logInfo("Server started on port %d", SERVER_PORT);
    
    // 主事件循环
    while (1) {
        int numEvents = epoll_wait(g_epollfd, events, MAX_EVENTS, -1);
        if (numEvents < 0) {
            logError("epoll_wait failed: %s", strerror(errno));
            continue;
        }
        
        for (int i = 0; i < numEvents; i++) {
            if (events[i].data.fd == serverfd) {
                // 新客户端连接
                clientAddrLen = sizeof(clientAddr);
                clientfd = accept(serverfd, (struct sockaddr *)&clientAddr, &clientAddrLen);
                if (clientfd < 0) {
                    logError("accept failed: %s", strerror(errno));
                    continue;
                }
                
                if (g_clientCount >= MAX_CLIENT_COUNT) {
                    logWarning("Max client count reached, rejecting connection");
                    close(clientfd);
                    continue;
                }
                
                addClientToEpoll(g_epollfd, clientfd, clientAddr);
            } else {
                // 客户端数据
                ClientInfo *client = (ClientInfo *)events[i].data.ptr;
                
                if (events[i].events & EPOLLIN) {
                    // 接收数据
                    char jsonBuffer[MAX_BUFFER_SIZE];
                    unsigned char dataType;
                    
                    int ret = recvPacket(client->sockfd, jsonBuffer, MAX_BUFFER_SIZE, &dataType);
                    if (ret > 0) {
                        // 创建任务
                        TaskData *task = (TaskData *)malloc(sizeof(TaskData));
                        task->client = client;
                        task->data = strdup(jsonBuffer);
                        task->dataLen = ret;
                        task->dataType = dataType;
                        
                        // 添加到线程池
                        if (threadPoolAddTask(g_threadPool, handleClientData, task) != 0) {
                            logError("Failed to add task to thread pool");
                            free(task->data);
                            free(task);
                        }
                    } else if (ret == 0 || errno != EAGAIN) {
                        // 客户端断开连接或发生错误
                        removeClientFromEpoll(g_epollfd, client);
                    }
                }
            }
        }
    }
    
    // 清理资源
    close(serverfd);
    close(g_epollfd);
    threadPoolDestroy(g_threadPool);
    logCleanup();
    
    return 0;
}